#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
性能监控模块
提供系统资源监控、性能统计和可视化组件
"""

import time
import socket
import multiprocessing
from datetime import datetime
from collections import deque
from typing import Optional, Dict, List, Tuple

from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, 
                           QProgressBar, QFrame, QGridLayout, QScrollArea)
from PyQt5.QtCore import QTimer, Qt, pyqtSignal
from PyQt5.QtGui import QFont, QPalette


class PerformanceData:
    """性能数据记录类"""
    def __init__(self, timestamp: str, text_length: int, processing_time: float, 
                 speed_ratio: float, segments: int):
        self.timestamp = timestamp
        self.text_length = text_length
        self.processing_time = processing_time
        self.speed_ratio = speed_ratio
        self.segments = segments


class SystemMonitor:
    """系统资源监控器"""
    
    def __init__(self):
        self.psutil_available = False
        self.total_memory_gb = 0
        self._init_psutil()
        
    def _init_psutil(self):
        """初始化psutil库"""
        try:
            import psutil
            self.psutil = psutil
            memory_info = psutil.virtual_memory()
            self.total_memory_gb = memory_info.total / (1024**3)
            self.psutil_available = True
        except ImportError:
            print("⚠️ psutil未安装，部分系统监控功能将不可用")
            print("💡 要启用完整的系统监控功能，请运行: pip install psutil")
            self.psutil = None
            
    def get_memory_usage(self) -> Tuple[float, float]:
        """获取内存使用情况
        
        Returns:
            Tuple[float, float]: (使用率百分比, 已用内存GB)
        """
        if not self.psutil_available:
            return 0.0, 0.0
            
        try:
            memory = self.psutil.virtual_memory()
            usage_percent = memory.percent
            used_gb = memory.used / (1024**3)
            return usage_percent, used_gb
        except Exception:
            return 0.0, 0.0
    
    def get_cpu_usage(self) -> float:
        """获取CPU使用率"""
        if not self.psutil_available:
            return 0.0
            
        try:
            return self.psutil.cpu_percent(interval=0.1)
        except Exception:
            return 0.0
    
    def test_network_latency(self, host: str = "speech.platform.bing.com", 
                           port: int = 443, timeout: int = 3) -> Tuple[bool, float]:
        """测试网络连通性和延迟
        
        Args:
            host: 目标主机
            port: 目标端口
            timeout: 超时时间
            
        Returns:
            Tuple[bool, float]: (是否连通, 延迟毫秒)
        """
        try:
            start_time = time.time()
            socket.create_connection((host, port), timeout=timeout).close()
            latency = (time.time() - start_time) * 1000
            return True, latency
        except Exception:
            return False, 0.0


class PerformanceMonitorWidget(QWidget):
    """性能监控面板组件"""
    
    # 信号定义
    performance_updated = pyqtSignal(dict)
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.system_monitor = SystemMonitor()
        self.performance_history = deque(maxlen=3)  # 减少历史记录数量，节省内存
        self.current_stats = {
            'threads': 0,
            'total_segments': 0,
            'active_tasks': 0,
            'processing_time': 0.0,
            'completed': 0,
            'speed_ratio': 1.0
        }
        
        self.init_ui()
        self.init_timers()
        
    def init_ui(self):
        """初始化用户界面"""
        self.setStyleSheet("""
            QWidget {
                background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                           stop:0 #ffffff, stop:1 #f8fafc);
                border: 2px solid #e2e8f0;
                border-radius: 16px;
                margin: 0;
                padding: 0;
            }
        """)
        
        layout = QVBoxLayout(self)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(15)
        
        # 标题
        title = QLabel("📊 性能监控中心")
        title.setFont(QFont("Microsoft YaHei", 14, QFont.Bold))
        title.setAlignment(Qt.AlignCenter)
        title.setStyleSheet("""
            QLabel {
                color: #1e293b;
                background: transparent;
                border: none;
                padding: 10px;
                border-radius: 8px;
            }
        """)
        layout.addWidget(title)
        
        # 创建滚动区域
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll_area.setStyleSheet("""
            QScrollArea {
                border: none;
                background: transparent;
            }
            QScrollBar:vertical {
                background: #f1f5f9;
                width: 8px;
                border-radius: 4px;
            }
            QScrollBar::handle:vertical {
                background: #cbd5e1;
                border-radius: 4px;
                min-height: 20px;
            }
            QScrollBar::handle:vertical:hover {
                background: #94a3b8;
            }
        """)
        
        # 内容容器
        content_widget = QWidget()
        content_layout = QVBoxLayout(content_widget)
        content_layout.setSpacing(15)
        
        # 创建各个监控面板
        self.create_processing_panel(content_layout)
        self.create_system_panel(content_layout)
        self.create_memory_panel(content_layout)
        self.create_network_panel(content_layout)
        self.create_health_panel(content_layout)
        self.create_history_panel(content_layout)
        
        scroll_area.setWidget(content_widget)
        layout.addWidget(scroll_area)
        
    def create_processing_panel(self, parent_layout):
        """创建处理状态面板"""
        frame = self._create_panel_frame("📊 并行处理状态")
        layout = frame.layout()  # 使用已创建的布局
        
        # 创建状态网格
        grid = QGridLayout()
        grid.setSpacing(3)  # 进一步减少间距
        grid.setHorizontalSpacing(6)  # 减少水平间距
        grid.setVerticalSpacing(6)  # 减少垂直间距
        
        # 状态标签
        self.status_labels = {}
        status_items = [
            ('工作线程', 'threads'),
            ('总段落', 'total_segments'),
            ('活跃任务', 'active_tasks'),
            ('处理时间', 'processing_time'),
            ('分段耗时', 'avg_segment_time'),
            ('已完成', 'completed'),
            ('加速倍数', 'speed_ratio')
        ]
        
        for i, (label_text, key) in enumerate(status_items):
            label = QLabel(f"{label_text}:")
            label.setStyleSheet("color: #64748b; font-weight: bold; min-width: 70px;")  # 进一步增加以确保完整显示
            value_label = QLabel("0")
            value_label.setStyleSheet("color: #0f172a; font-weight: bold; min-width: 60px;")  # 大幅增加以显示长数字如上千秒
            
            grid.addWidget(label, i // 2, (i % 2) * 2)
            grid.addWidget(value_label, i // 2, (i % 2) * 2 + 1)
            self.status_labels[key] = value_label
            
        # 设置列的拉伸因子，让标签列和数值列更紧凑
        grid.setColumnStretch(0, 0)  # 标签列不拉伸
        grid.setColumnStretch(1, 0)  # 数值列不拉伸
        grid.setColumnStretch(2, 0)  # 标签列不拉伸
        grid.setColumnStretch(3, 0)  # 数值列不拉伸
            
        layout.addLayout(grid)
        parent_layout.addWidget(frame)
        
    def create_system_panel(self, parent_layout):
        """创建系统信息面板"""
        frame = self._create_panel_frame("💻 系统信息")
        layout = frame.layout()  # 使用已创建的布局
        
        # CPU信息
        cpu_cores = multiprocessing.cpu_count()
        recommended_threads = min(max(2, cpu_cores * 2), 16)
        
        cpu_info = QLabel(f"CPU核心: {cpu_cores} 个")
        cpu_info.setStyleSheet("color: #64748b; margin: 2px 0;")
        layout.addWidget(cpu_info)
        
        thread_info = QLabel(f"推荐线程: {recommended_threads} 个")
        thread_info.setStyleSheet("color: #64748b; margin: 2px 0;")
        layout.addWidget(thread_info)
        
        # CPU使用率
        self.cpu_label = QLabel("CPU使用率: --")
        self.cpu_label.setStyleSheet("color: #0f172a; font-weight: bold; margin: 5px 0;")
        layout.addWidget(self.cpu_label)
        
        parent_layout.addWidget(frame)
        
    def create_memory_panel(self, parent_layout):
        """创建内存监控面板"""
        frame = self._create_panel_frame("💾 内存使用")
        layout = frame.layout()  # 使用已创建的布局
        
        # 内存信息标签
        self.memory_label = QLabel("内存使用率: --")
        self.memory_label.setStyleSheet("color: #0f172a; font-weight: bold; margin-bottom: 5px;")
        layout.addWidget(self.memory_label)
        
        # 内存使用进度条
        self.memory_progress = QProgressBar()
        self.memory_progress.setRange(0, 100)
        self.memory_progress.setTextVisible(True)
        self.memory_progress.setStyleSheet("""
            QProgressBar {
                border: 2px solid #e2e8f0;
                border-radius: 8px;
                text-align: center;
                font-weight: bold;
                background: #f8fafc;
                height: 25px;
            }
            QProgressBar::chunk {
                border-radius: 6px;
                background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                           stop:0 #10b981, stop:0.7 #10b981, 
                           stop:0.8 #f59e0b, stop:1 #ef4444);
            }
        """)
        layout.addWidget(self.memory_progress)
        
        # 详细内存信息
        self.memory_detail = QLabel("详细信息: --")
        self.memory_detail.setStyleSheet("color: #64748b; font-size: 11px; margin-top: 5px;")
        layout.addWidget(self.memory_detail)
        
        parent_layout.addWidget(frame)
        
    def create_network_panel(self, parent_layout):
        """创建网络状态面板"""
        frame = self._create_panel_frame("🌐 网络状态")
        layout = frame.layout()  # 使用已创建的布局
        
        # 网络状态标签
        self.network_status = QLabel("🟡 正在检测...")
        self.network_status.setStyleSheet("color: #0f172a; font-weight: bold; margin-bottom: 5px;")
        layout.addWidget(self.network_status)
        
        # 延迟信息
        self.latency_label = QLabel("延迟: --")
        self.latency_label.setStyleSheet("color: #64748b; margin: 2px 0;")
        layout.addWidget(self.latency_label)
        
        parent_layout.addWidget(frame)
        
    def create_health_panel(self, parent_layout):
        """创建系统健康面板"""
        frame = self._create_panel_frame("🎯 系统健康")
        layout = frame.layout()  # 使用已创建的布局
        
        # 健康指示器
        health_layout = QHBoxLayout()
        self.health_indicator = QLabel("●")
        self.health_indicator.setFont(QFont("Arial", 24))
        self.health_indicator.setStyleSheet("color: #10b981;")
        self.health_indicator.setAlignment(Qt.AlignCenter)
        
        self.health_text = QLabel("系统运行正常")
        self.health_text.setStyleSheet("color: #0f172a; font-weight: bold;")
        self.health_text.setAlignment(Qt.AlignCenter)
        
        health_layout.addWidget(self.health_indicator)
        health_layout.addWidget(self.health_text)
        layout.addLayout(health_layout)
        
        parent_layout.addWidget(frame)
        
    def create_history_panel(self, parent_layout):
        """创建性能历史面板"""
        frame = self._create_panel_frame("📈 性能历史")
        layout = frame.layout()  # 使用已创建的布局
        
        # 历史记录标签
        self.history_label = QLabel("暂无转换记录")
        self.history_label.setStyleSheet("""
            color: #64748b; 
            font-size: 11px; 
            padding: 10px;
            background: #f8fafc;
            border-radius: 6px;
            border: 1px solid #e2e8f0;
        """)
        self.history_label.setWordWrap(True)
        layout.addWidget(self.history_label)
        
        parent_layout.addWidget(frame)
        
    def _create_panel_frame(self, title: str) -> QFrame:
        """创建面板框架"""
        frame = QFrame()
        frame.setFrameStyle(QFrame.StyledPanel)
        frame.setStyleSheet("""
            QFrame {
                background: #ffffff;
                border: 1px solid #e2e8f0;
                border-radius: 10px;
                padding: 10px;
                margin: 2px;
            }
        """)
        
        # 添加标题
        main_layout = QVBoxLayout(frame)
        main_layout.setContentsMargins(15, 15, 15, 15)
        main_layout.setSpacing(10)
        
        title_label = QLabel(title)
        title_label.setFont(QFont("Microsoft YaHei", 11, QFont.Bold))
        title_label.setStyleSheet("color: #1e293b; margin-bottom: 5px; border: none; background: transparent;")
        main_layout.addWidget(title_label)
        
        return frame
        
    def init_timers(self):
        """初始化定时器 - 优化更新频率"""
        # 系统监控定时器 - 降低更新频率减少主线程阻塞
        self.system_timer = QTimer()
        self.system_timer.timeout.connect(self.update_system_stats)
        self.system_timer.start(3000)  # 每3秒更新一次，减少CPU占用
        
        # 网络检测定时器 - 进一步降低频率
        self.network_timer = QTimer()
        self.network_timer.timeout.connect(self.update_network_status)
        self.network_timer.start(15000)  # 每15秒检测一次，减少网络请求
        
    def update_processing_stats(self, stats: Dict):
        """更新处理状态统计"""
        try:
            print(f"[调试] 性能监控收到数据: {stats}")
            self.current_stats.update(stats)
            
            # 更新标签
            self.status_labels['threads'].setText(str(stats.get('threads', 0)))
            self.status_labels['total_segments'].setText(str(stats.get('total_segments', 0)))
            self.status_labels['active_tasks'].setText(str(stats.get('active_tasks', 0)))
            self.status_labels['processing_time'].setText(f"{stats.get('processing_time', 0):.1f}s")
            self.status_labels['avg_segment_time'].setText(f"{stats.get('avg_segment_time', 0):.2f}s")
            self.status_labels['completed'].setText(str(stats.get('completed', 0)))
            self.status_labels['speed_ratio'].setText(f"{stats.get('speed_ratio', 1.0):.1f}x")
            
            print("[调试] 性能监控UI已更新")
        except Exception as e:
            print(f"[错误] 更新性能监控UI失败: {e}")
            import traceback
            traceback.print_exc()
        
    def update_system_stats(self):
        """更新系统统计信息"""
        # 更新CPU使用率
        cpu_usage = self.system_monitor.get_cpu_usage()
        self.cpu_label.setText(f"CPU使用率: {cpu_usage:.1f}%")
        
        # 更新内存使用率
        memory_percent, memory_used = self.system_monitor.get_memory_usage()
        if self.system_monitor.psutil_available:
            self.memory_label.setText(f"内存使用率: {memory_percent:.1f}%")
            self.memory_progress.setValue(int(memory_percent))
            self.memory_detail.setText(
                f"已用: {memory_used:.1f} GB / 总计: {self.system_monitor.total_memory_gb:.1f} GB"
            )
            
            # 更新进度条颜色
            if memory_percent < 70:
                color = "#10b981"  # 绿色
            elif memory_percent < 85:
                color = "#f59e0b"  # 橙色
            else:
                color = "#ef4444"  # 红色
                
            self.memory_progress.setStyleSheet(f"""
                QProgressBar {{
                    border: 2px solid #e2e8f0;
                    border-radius: 8px;
                    text-align: center;
                    font-weight: bold;
                    background: #f8fafc;
                    height: 25px;
                }}
                QProgressBar::chunk {{
                    border-radius: 6px;
                    background: {color};
                }}
            """)
        else:
            self.memory_label.setText("内存使用率: 需要psutil")
            self.memory_detail.setText("安装psutil以获取详细信息")
            
        # 更新系统健康状态
        self.update_health_status(cpu_usage, memory_percent)
        
    def update_network_status(self):
        """更新网络状态"""
        is_connected, latency = self.system_monitor.test_network_latency()
        
        if is_connected:
            if latency < 100:
                self.network_status.setText("🟢 网络连接良好")
                status_color = "#10b981"
            elif latency < 300:
                self.network_status.setText("🟡 网络连接一般")
                status_color = "#f59e0b"
            else:
                self.network_status.setText("🟠 网络连接较慢")
                status_color = "#f97316"
            self.latency_label.setText(f"延迟: {latency:.0f}ms")
        else:
            self.network_status.setText("🔴 网络连接失败")
            self.latency_label.setText("延迟: 超时")
            status_color = "#ef4444"
            
        self.network_status.setStyleSheet(f"color: {status_color}; font-weight: bold; margin-bottom: 5px;")
        
    def update_health_status(self, cpu_usage: float, memory_percent: float):
        """更新系统健康状态"""
        # 计算健康分数
        health_score = 100
        
        if cpu_usage > 80:
            health_score -= 30
        elif cpu_usage > 60:
            health_score -= 15
            
        if memory_percent > 85:
            health_score -= 40
        elif memory_percent > 70:
            health_score -= 20
            
        # 根据分数设置状态
        if health_score >= 80:
            self.health_indicator.setStyleSheet("color: #10b981; font-size: 24px;")
            self.health_text.setText("系统运行良好")
            self.health_text.setStyleSheet("color: #10b981; font-weight: bold;")
        elif health_score >= 60:
            self.health_indicator.setStyleSheet("color: #f59e0b; font-size: 24px;")
            self.health_text.setText("系统负载偏高")
            self.health_text.setStyleSheet("color: #f59e0b; font-weight: bold;")
        else:
            self.health_indicator.setStyleSheet("color: #ef4444; font-size: 24px;")
            self.health_text.setText("系统负载过高")
            self.health_text.setStyleSheet("color: #ef4444; font-weight: bold;")
            
    def add_performance_record(self, text_length: int, processing_time: float, 
                             speed_ratio: float, segments: int):
        """添加性能记录"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        record = PerformanceData(timestamp, text_length, processing_time, speed_ratio, segments)
        self.performance_history.append(record)
        self.update_history_display()
        
    def update_history_display(self):
        """更新历史记录显示"""
        if not self.performance_history:
            self.history_label.setText("暂无转换记录")
            return
            
        history_text = "最近转换记录:\n\n"
        
        for i, record in enumerate(reversed(list(self.performance_history)), 1):
            history_text += (
                f"{i}. {record.timestamp}\n"
                f"   文本: {record.text_length}字 | "
                f"时长: {record.processing_time:.1f}s\n"
                f"   加速: {record.speed_ratio:.1f}x | "
                f"段落: {int(record.segments)}个\n\n"
            )
            
        # 添加统计摘要
        avg_time = sum(r.processing_time for r in self.performance_history) / len(self.performance_history)
        avg_speed = sum(r.speed_ratio for r in self.performance_history) / len(self.performance_history)
        total_chars = sum(r.text_length for r in self.performance_history)
        total_segments = sum(r.segments for r in self.performance_history)
        
        # 计算正确的平均段处理时间：总时间/总段数
        if total_segments > 0:
            avg_segment_time = sum(r.processing_time for r in self.performance_history) / total_segments
        else:
            avg_segment_time = 0
        
        # 计算平均段数 (确保是整数显示)
        avg_segments = total_segments / len(self.performance_history) if self.performance_history else 0
        
        history_text += (
            f"📊 统计摘要:\n"
            f"平均总处理时间: {avg_time:.1f}s\n"
            f"平均段处理时间: {avg_segment_time:.2f}s\n"
            f"平均加速倍数: {avg_speed:.1f}x\n"
            f"平均段数: {avg_segments:.0f}个\n"
            f"总处理字符: {total_chars}字"
        )
        
        self.history_label.setText(history_text)
        
    def cleanup(self):
        """清理资源"""
        if hasattr(self, 'system_timer'):
            self.system_timer.stop()
        if hasattr(self, 'network_timer'):
            self.network_timer.stop()


if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication, QMainWindow
    
    app = QApplication(sys.argv)
    
    # 创建测试窗口
    window = QMainWindow()
    window.setWindowTitle("性能监控测试")
    window.setGeometry(100, 100, 400, 800)
    
    # 创建监控组件
    monitor = PerformanceMonitorWidget()
    window.setCentralWidget(monitor)
    
    # 模拟数据更新
    def update_test_data():
        import random
        stats = {
            'threads': random.randint(2, 8),
            'total_segments': random.randint(10, 50),
            'active_tasks': random.randint(0, 8),
            'processing_time': random.uniform(1.0, 10.0),
            'completed': random.randint(0, 50),
            'speed_ratio': random.uniform(0.8, 3.0)
        }
        monitor.update_processing_stats(stats)
        
        # 模拟添加性能记录
        if random.random() < 0.3:  # 30%概率添加记录
            monitor.add_performance_record(
                random.randint(100, 1000),
                random.uniform(2.0, 15.0),
                random.uniform(1.0, 3.0),
                random.randint(5, 20)
            )
    
    # 创建定时器更新测试数据
    test_timer = QTimer()
    test_timer.timeout.connect(update_test_data)
    test_timer.start(3000)
    
    window.show()
    sys.exit(app.exec_())
